const dataMappers = {
    img: {
        defaultValue: () => {
            return []
        },
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    checkbox: {
        defaultValue: () => {
            return []
        },
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },

    },
    upload: {
        defaultValue: () => {
            return null
        },
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    url: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    array: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    map: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    daterange: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    timerange: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    datetimerange: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    },
    tree: {
        columnFormat: {
            format: jsonFormat,
        },
        saveFormat: {
            format: toJsonStrFormat,
        },
    }
}

function toJsonStrFormat(column, data, value) {
    if (!value) return null;
    if (value instanceof Array) return JSON.stringify(value);
    if (value instanceof Object) return JSON.stringify(value);
    return value;
}

function jsonFormat(column, data, value) {
    if (!value) return null;
    try {
        return JSON.parse(value)
    } catch (e) {
        return value
    }
}

function columnsToMapData(columns) {
    if (!columns) return null;
    if (!(columns instanceof Array)) return columns;
    let colMap = {}
    for (let i = 0; i < columns.length; i++) {
        let col = columns[i];
        if (!col.type) col.type = "input";
        let mapKey = col.prop;
        let mapValue = col
        if (colMap[mapKey]) continue;
        colMap[mapKey] = mapValue
    }
    return colMap;
}

/**
 * 数组数据 适配数据转换器
 * @param columns
 * @param listData
 * @param action
 */
function adapterList(columns, listData, action = 'columnFormat') {
    if (!columns) return;
    if (columns.length < 1) return
    if (!listData) return;
    if (columns instanceof Array) {
        columns = columnsToMapData(columns)
    }
    for (let i = 0; i < listData.length; i++) {
        adapter(columns, listData[i])
    }
}

/**
 * 适配数据转换器
 * @param columns
 * @param data
 * @param action
 */
function adapter(columns, data, action = 'columnFormat') {
    if (!columns) return
    if (columns instanceof Array) {
        columns = columnsToMapData(columns)
    }
    for (const colKey in columns) {
        let column = columns[colKey];
        let columnType = column.type;
        if (!dataMappers[columnType]) continue
        let dataMapper = dataMappers[columnType];
        if (!dataMapper[action]) continue
        let format = dataMapper[action];
        if (!data[colKey]) continue
        let columnData = data[colKey]
        try {
            data[colKey] = format.format(columns, data, columnData)
        } catch (e) {
            console.log(e);
        }
    }
}

function transformDataList(columns, data, action = 'columnFormat') {
    if (!columns) return;
    if (columns.length < 1) return
    let columnsToMap = columnsToMapData(columns);
    if (!data) return;
    if (data instanceof Array) {
        return adapterList(columnsToMap, data, action)
    } else {
        return adapter(columnsToMap, data, action)
    }
}

function transformDataSave(columns, data) {
    transformDataList(columns, data, 'saveFormat')
}

const avueDataAdapter = {
    transformDataList,
    transformDataSave
};

export default avueDataAdapter;
